package compiler

import (
	"equantum/model"
	"sync"

	"github.com/gin-gonic/gin"
)

var Wg sync.WaitGroup
var Channel chan gin.H

const nssym int = 256  // 单字符个数
const txmax int = 100  // 符号表容量
const norw int = 25    // 保留字个数
const nerr int = 20    // 出错原因数
const stkmax int = 100 // 数据栈容量
const parmax int = 20  // gate参数上限

/* 符号 */
const (
	nul = iota
	ident
	integer
	floating
	// 符号 ////////
	plus // 单分界符 (11)
	minus
	times
	slash
	lparen
	rparen
	lbrack
	rbrack
	lbrace
	rbrace
	stop
	comma
	semicolon
	// 保留字 ////////
	qregsym
	gatesym
	idgate // gate
	xgate
	ygate
	zgate
	hgate
	sgate
	sdggate
	tgate
	tdgate
	cxgate
	cygate
	czgate
	chgate
	swapgate
	ccxgate
	cswapgate
	ugate
	rxgate
	rygate
	rzgate
	cugate
	measurezgate
	pisym // 占位用，wsym = floating
)

/* 符号表的类型 */
const (
	qreg_t  = iota // 量子比特寄存器
	greg_t         // 量子门内的量子比特寄存器，同一时刻至多一个活跃的
	gate_t         // 自定义量子门
	param_t        // 量子门的参数
)

/* 符号表结构 */
type table_t struct {
	name string // 变量名
	kind int    // 变量类型
	val  int    // 寄存器长度/gate 参数个数/param参数次序
}

/* q[x]类型 */
const (
	decla = iota // 声明量子寄存器
	use          // 访问量子比特
)

/* 描述线路图用的量子门结构 */
type QGate struct {
	ID     uint      `json:"id"`
	Name   string    `json:"name"`  // 量子门名字
	Type   int       `json:"type"`  //
	Input  int       `json:"input"` // 输入量子比特数
	Param  int       `json:"param"`
	Params []float64 `json:"params"`
	UserID uint      `json:"userid"`
	Code   string    `json:"code"`
	// Circuit [][]qgate_t // 用户自定义量子门的线路
}

/* 量子线路抽象 */
type QCircuit struct {
	Nqubit  int       `json:"nqubit"`  // 量子比特数
	Circuit [][]QGate `json:"circuit"` // 量子线路
}

/* 基本量子门信息 */
var InitGates = []model.Gate{
	{Name: "id", Type: 0, Input: 1, Param: 0},
	{Name: "x", Type: 1, Input: 1, Param: 0},
	{Name: "y", Type: 1, Input: 1, Param: 0},
	{Name: "z", Type: 1, Input: 1, Param: 0},
	{Name: "h", Type: 1, Input: 1, Param: 0},
	{Name: "s", Type: 1, Input: 1, Param: 0},
	{Name: "sdg", Type: 1, Input: 1, Param: 0},
	{Name: "t", Type: 1, Input: 1, Param: 0},
	{Name: "tdg", Type: 1, Input: 1, Param: 0},
	{Name: "rx", Type: 2, Input: 1, Param: 1},
	{Name: "ry", Type: 2, Input: 1, Param: 1},
	{Name: "rz", Type: 2, Input: 1, Param: 1},
	{Name: "cx", Type: 3, Input: 2, Param: 0},
	{Name: "cy", Type: 3, Input: 2, Param: 0},
	{Name: "cz", Type: 3, Input: 2, Param: 0},
	{Name: "swap", Type: 3, Input: 2, Param: 0},
	{Name: "measure", Type: 4, Input: 1, Param: 0},
}
